package com.manage.common.filter;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.manage.common.result.Result;
import com.manage.common.utils.AESUtil;
import com.manage.common.utils.JwtUtil;
import com.manage.dao.CmSysUserMapper;
import com.manage.pojo.dto.LoginDTO;
import com.manage.pojo.entity.CmSysUser;
import com.manage.pojo.entity.LoginBody;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.Cookie;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationServiceException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import java.io.IOException;
import java.util.ArrayList;

public class JWTAuthenticationFilter extends UsernamePasswordAuthenticationFilter {

    private final AuthenticationManager authenticationManager;
    private final AESUtil aesUtil;

    private final CmSysUserMapper cmSysUserMapper;

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager, AESUtil aesUtil, CmSysUserMapper cmSysUserMapper) {
        this.authenticationManager = authenticationManager;
        this.aesUtil = aesUtil;
        this.cmSysUserMapper = cmSysUserMapper;
        super.setFilterProcessesUrl("/auth/login");
    }

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request,
                                                HttpServletResponse response) throws AuthenticationException {
        try {
            // 确保请求体是 JSON 格式
            if (request.getContentType() == null || !request.getContentType().contains("application/json")) {
                throw new AuthenticationServiceException("请求内容类型必须是 application/json");
            }

            // 读取请求体3632478
            LoginBody loginUser = new ObjectMapper().readValue(request.getInputStream(), LoginBody.class);

            // 验证登录信息是否为空
            if (loginUser.getUsername() == null || loginUser.getPassword() == null) {
                throw new AuthenticationServiceException("用户名和密码不能为空");
            }
            // 解密密码
            String decryptedPassword;
            try {
                decryptedPassword = aesUtil.decrypt(loginUser.getPassword());
            } catch (Exception e) {
                throw new AuthenticationServiceException("密码解密失败", e);
            }

            // 使用解密后的密码进行认证
            return authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(
                            loginUser.getUsername(),
                            decryptedPassword,
                            new ArrayList<>())
            );

        } catch (IOException e) {
            throw new AuthenticationServiceException("解析登录信息失败", e);
        }
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult) throws IOException, ServletException {
        JwtUser jwtUser = (JwtUser) authResult.getPrincipal();
        String token = new JwtUtil().generateToken(jwtUser.getUsername());
// 2. 创建 HttpOnly Cookie 存储 token（核心修改）
        Cookie authCookie = new Cookie("auth_token", token); // Cookie 名称自定义（如 auth_token）
        authCookie.setHttpOnly(true); // 关键：开启 HttpOnly，防止 JS 访问
        authCookie.setPath("/"); // 生效路径：整个应用均可访问该 Cookie
        authCookie.setMaxAge(7200); // 过期时间：7200 秒（2 小时，根据需求调整）
        authCookie.setAttribute("SameSite", "Lax"); // 限制跨站发送，降低 CSRF 风险
        // 3. 将 Cookie 添加到响应中（浏览器会自动存储）
        response.addCookie(authCookie);
        Result result = new Result();
        result.setCode(200);
        result.setMessage("success");
        CmSysUser user = cmSysUserMapper.selectOne(
                Wrappers.<CmSysUser>lambdaQuery()
                        .eq(CmSysUser::getUsername, jwtUser.getUsername())
                        .isNull(CmSysUser::getDeleteTime)
        );
        LoginDTO loginDTO=BeanUtil.toBean(user, LoginDTO.class);
        result.setData(loginDTO);
        response.setContentType("application/json;charset=UTF-8");
        response.getWriter().write(new ObjectMapper().writeValueAsString(result));
    }

    @Override
    protected void unsuccessfulAuthentication(HttpServletRequest request,
                                              HttpServletResponse response,
                                              AuthenticationException failed) throws IOException, ServletException {
        response.setContentType("application/json;charset=UTF-8");
        response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);

        Result result = new Result();
        result.setCode(500);
        result.setMessage(failed.getMessage() != null ? failed.getMessage() : "认证失败");

        response.getWriter().write(new ObjectMapper().writeValueAsString(result));
    }
}
